using Engine.Graphics;
using System;
using System.Windows.Forms;

namespace WorldRacing2.Material
{
    public partial class MaterialEditUI : UserControl, Scenario_Editor.AddinManager.IMaterialEditorControl
    {
        #region Private Fields

        private Wr2Material _currentMaterial;
        private bool duringMaterialChange = false;

        /// <summary>
        /// Reference to the Material Manager.
        /// </summary>
        private MaterialManager materialManager;

        private System.Drawing.Bitmap texture;

        #endregion Private Fields

        #region Public Constructors

        public MaterialEditUI()
        {
            InitializeComponent();

            materialMappingsMatrix_Texture1.materialChange += new WorldRacing2.WindowsFormsControls.MaterialMappingsMatrixWr2.OnMaterialChange(OnMaterialMappingMatrixChange);
            materialMappingsMatrix_Texture2.materialChange += new WorldRacing2.WindowsFormsControls.MaterialMappingsMatrixWr2.OnMaterialChange(OnMaterialMappingMatrixChange);
            materialMappingsMatrix_Texture3.materialChange += new WorldRacing2.WindowsFormsControls.MaterialMappingsMatrixWr2.OnMaterialChange(OnMaterialMappingMatrixChange);

            this.comboBox_SelectedMappingMode.DataSource = Enum.GetValues(typeof(EnumMappingMode));
        }

        #endregion Public Constructors

        #region Internal Delegates

        internal delegate void MaterialChange(object material, EventArgs e);

        #endregion Internal Delegates

        #region Public Events

        public event EventHandler MaterialChanged;

        #endregion Public Events

        #region Public Properties

        public Wr2Material CurrentMaterial
        {
            get { return _currentMaterial; }
            set { _currentMaterial = value; }
        }

        #endregion Public Properties

        #region Public Methods

        public IMaterial CreateMaterialFromTextureName(string textureName)
        {
            int textureID = this.materialManager.GetTextureID(textureName);

            if (textureID > -1)
            {
                return new Wr2Material(textureID, textureID, textureID, EnumMappingMode.material32, this.materialManager);
            }

            return new Wr2Material(0, 0, 0, EnumMappingMode.material32, this.materialManager);
        }

        public IMaterial GetMaterial()
        {
            return this.CurrentMaterial;
        }

        public IMaterial GetNewMaterial()
        {
            this.CurrentMaterial = new Wr2Material()
            {
                TextureName1 = this.comboBox_Texture1.Text,
                TextureName2 = this.comboBox_Texture2.Text,
                TextureName3 = this.comboBox_Texture3.Text,
                TextureID1 = this.comboBox_Texture1.SelectedIndex,
                TextureID2 = this.comboBox_Texture2.SelectedIndex,
                TextureID3 = this.comboBox_Texture3.SelectedIndex,
                Mappings1 = this.materialMappingsMatrix_Texture1.Mapping,
                Mappings2 = this.materialMappingsMatrix_Texture2.Mapping,
                Mappings3 = this.materialMappingsMatrix_Texture3.Mapping,
                MappingMode = (EnumMappingMode)this.comboBox_SelectedMappingMode.SelectedItem
            };
            this.CurrentMaterial.UpdateTextureName(materialManager);

            return new Wr2Material()
            {
                TextureName1 = this.CurrentMaterial.TextureName1,
                TextureName2 = this.CurrentMaterial.TextureName2,
                TextureName3 = this.CurrentMaterial.TextureName3,
                TextureID1 = this.CurrentMaterial.TextureID1,
                TextureID2 = this.CurrentMaterial.TextureID2,
                TextureID3 = this.CurrentMaterial.TextureID3,
                Mappings1 = this.CurrentMaterial.Mappings1,
                Mappings2 = this.CurrentMaterial.Mappings2,
                Mappings3 = this.CurrentMaterial.Mappings3,
                MappingMode = this.CurrentMaterial.MappingMode
            };
        }

        public void SetMaterial(IMaterial material)
        {
            this.CurrentMaterial = new Wr2Material((Wr2Material)material);
            this.CurrentMaterial.UpdateTextureIDs(this.materialManager);

            duringMaterialChange = true;
            this.comboBox_SelectedMappingMode.SelectedItem = this.CurrentMaterial.MappingMode;
            this.comboBox_Texture1.SelectedIndex = Math.Max(0, this.CurrentMaterial.TextureID1);
            this.comboBox_Texture2.SelectedIndex = Math.Max(0, this.CurrentMaterial.TextureID2);
            this.comboBox_Texture3.SelectedIndex = Math.Max(0, this.CurrentMaterial.TextureID3);
            this.materialMappingsMatrix_Texture1.Mapping = this.CurrentMaterial.Mappings1;
            this.materialMappingsMatrix_Texture2.Mapping = this.CurrentMaterial.Mappings2;
            this.materialMappingsMatrix_Texture3.Mapping = this.CurrentMaterial.Mappings3;

            // Set image for preview from texture 1;
            UpdateImage(this.comboBox_Texture1.SelectedIndex);

            duringMaterialChange = false;
        }

        public void SetMaterialManager(object materialManagerInput, EventArgs e)
        {
            MaterialManager newMaterialManager = (MaterialManager)materialManagerInput;

            if (newMaterialManager != null)
            {
                this.materialManager = newMaterialManager;
                UpdateComboBoxes(this.materialManager.TextureNames.ToArray());
                // UpdateComboBoxes(new string[] { this.materialManager.TextureNames[0] });
            }
        }

        #endregion Public Methods

        #region Internal Methods

        /// <summary>
        /// Insert the Texturenames in the comboboxes
        /// </summary>
        /// <param name="textureNames">the list with full paths to the textures</param>
        internal void UpdateComboBoxes(string[] textureNames)
        {
            comboBox_Texture1.Items.Clear();
            comboBox_Texture2.Items.Clear();
            comboBox_Texture3.Items.Clear();

            comboBox_Texture1.Items.AddRange(textureNames);
            comboBox_Texture2.Items.AddRange(textureNames);
            comboBox_Texture3.Items.AddRange(textureNames);
            duringMaterialChange = true;
            comboBox_Texture1.SelectedIndex = 0;
            comboBox_Texture2.SelectedIndex = 0;
            comboBox_Texture3.SelectedIndex = 0;
            duringMaterialChange = false;
        }

        #endregion Internal Methods

        #region Private Methods

        private void comboBox_SelectedMappingMode_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!duringMaterialChange)
            {
                duringMaterialChange = true;
                if (this.CurrentMaterial != null)
                {
                    this.CurrentMaterial.MappingMode = (EnumMappingMode)this.comboBox_SelectedMappingMode.SelectedItem;

                    if (this.MaterialChanged != null)
                        this.MaterialChanged(this.CurrentMaterial, null);
                }

                duringMaterialChange = false;
            }
        }

        private void comboBox_selectedTextureChanged(object sender, EventArgs e)
        {
            ComboBox combolist = (ComboBox)sender;

            if (!duringMaterialChange && this.CurrentMaterial != null)
            {
                duringMaterialChange = true;
                //Get the material whhich should be changed
                Wr2Material material = this.CurrentMaterial;

                //Set the textureIDs
                if (comboBox_Texture1.Focused)
                {
                    material.TextureID1 = comboBox_Texture1.SelectedIndex;
                    UpdateImage(comboBox_Texture1.SelectedIndex);
                }
                if (comboBox_Texture2.Focused)
                {
                    material.TextureID2 = comboBox_Texture2.SelectedIndex;
                    UpdateImage(comboBox_Texture2.SelectedIndex);
                }
                if (comboBox_Texture3.Focused)
                {
                    material.TextureID3 = comboBox_Texture3.SelectedIndex;
                    UpdateImage(comboBox_Texture3.SelectedIndex);
                }

                material.UpdateTextureName(this.materialManager);
                //Load the textures if needed
                if (comboBox_Texture1.SelectedIndex > -1)
                    this.materialManager.LoadTextureID(comboBox_Texture1.SelectedIndex);

                if (comboBox_Texture2.SelectedIndex > -1)
                    this.materialManager.LoadTextureID(comboBox_Texture2.SelectedIndex);

                if (comboBox_Texture3.SelectedIndex > -1)
                    this.materialManager.LoadTextureID(comboBox_Texture3.SelectedIndex);

                if (MaterialChanged != null)
                    MaterialChanged(this.CurrentMaterial, null);

                duringMaterialChange = false;
            }
        }

        private void OnMaterialMappingMatrixChange(object material, EventArgs e)
        {
            if (!duringMaterialChange)
            {
                duringMaterialChange = true;

                Wr2Material material2 = CurrentMaterial;
                material2.Mappings1 = this.materialMappingsMatrix_Texture1.Mapping;
                material2.Mappings2 = this.materialMappingsMatrix_Texture2.Mapping;
                material2.Mappings3 = this.materialMappingsMatrix_Texture3.Mapping;

                if (MaterialChanged != null)
                    MaterialChanged(this.CurrentMaterial, null);
                duringMaterialChange = false;
            }
        }

        private void UpdateImage(int textureIndex)
        {
            if (texture != null)
                texture.Dispose();

            string fileName = materialManager.TexturePaths[textureIndex];

            try
            {
                texture = Ptx2bmpConverter.Ptx2bmp.FromFile(fileName);

                // Update the Preview Panel
                if (texture.Size.Width > this.pictureBox1.ClientSize.Width)
                {
                    this.pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
                }
                else
                {
                    this.pictureBox1.SizeMode = PictureBoxSizeMode.Normal;
                }

                if (this.pictureBox1.Image != null)
                    this.pictureBox1.Image.Dispose();

                this.pictureBox1.Image = texture;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error in Loading PTX-Texutre: " + fileName + "\n" + ex.Message);
            }
        }

        #endregion Private Methods
    }
}